/**
 * @file XXXMsgManager.h
 * @author huangxiaozhu (xiaozhuhuang2014@163.com)
 * @brief  XXX 协议消息处理者，上位机下发的请求消息和状态上报的响应消息处理
 * @version 1.0.0
 * @date 2024-02-26
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#pragma once

#include <tools/TcpServer/Session.h>
#include <tools/ManagerFactory/BaseManager.h>
#include <tools/Timer/Timer.h>
#include "MsgHandler/ConfigMsgHandler.h"
#include "MsgHandler/BaseMsgHandler.h"
#include "MsgReporter/BaseMsgReporter.h"    
#include <string>
#include <unordered_map>
#include <memory>


using MsgHandlerMap = std::unordered_map<std::string, BaseMsgHandlerPtr>;       // 请求处理者的绑定  type 对应【请求】消息类型
using MsgReporterMap = std::unordered_map<std::string, BaseMsgReporterPtr>;     // 响应处理者的绑定  type 对应【响应】消息类型

class XXXMsgManager;
using XXXMsgManagerPtr = std::shared_ptr<XXXMsgManager>;

class XXXMsgManager : public BaseManager
{
public:
    XXXMsgManager(const std::string& name = "");
    virtual ~XXXMsgManager();

    virtual bool Init() override;
    void InitMsgHandler();
    void InitMsgReporter();

    void Reset();
    virtual void Destroy() override;
    void SetSessionPtr(SessionPtr sessionPtr);

    bool IsConfigSuccess();                                   // 第一个配置请求是否配置成功

    bool HandleMsg(const std::string& msg);                   // 处理消息，响应消息
    void SetReportTimer();                                    // 数据上报的定时器


    // 注册消息处理者
    template <typename T>
    bool RegisterMsgHandler()
    {
        if (std::is_base_of<BaseMsgHandler, T>::value)
        {
            std::shared_ptr<T> ptr = std::make_shared<T>();
            m_msgHandlerMap.insert(std::make_pair(ptr->GetMsgType(), ptr));
            return true;
        }
        return false;
    }

    // 注册消息上报者
    template <typename T>
    bool RegisterMsgReporter()
    {
        if (std::is_base_of<BaseMsgReporter, T>::value)
        {
            std::shared_ptr<T> ptr = std::make_shared<T>();
            m_msgReporterMap.insert(std::make_pair(ptr->GetMsgType(), ptr));
            return true;
        }
        return false; 
    }

protected:
    bool SendMsg(const std::string& msg);                   // 异步发送消息
    bool HandleConfigMsg(const std::string& msg);           // 处理config消息
    void ReportMsg(BaseMsgReporterPtr& msgReporterPtr);

    virtual std::string GetMsgType(const std::string& msg);

private:
    bool m_initSuccess = false;                             // 是否初始化
    bool m_configSuccess = false;                           // 是否初始化，收到客户端的config消息，才表示通讯链接成功
    Timer m_ReportTimer;                                    // 上报消息定时器

    ConfigMsgHandlerPtr m_configMsgHandlerPtr = nullptr;    // 配置请求处理者，单独定义消息的处理者，用于初始化配置【不一定需要此特殊消息】

    MsgHandlerMap m_msgHandlerMap;                          // 请求处理者的绑定，不包含config消息处理者
    MsgReporterMap m_msgReporterMap;                        // 响应处理者的绑定，不包含config消息上报者

    SessionPtr m_sessionPtr = nullptr;                      // 当前会话连接者，用于上报消息
};